﻿#region Imports
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using DataAnnotationsContrib.Interfaces;
using DataAnnotationsContrib.Tests.Framework;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections;
#endregion

namespace DataAnnotationsContrib.Tests
{
    /// <summary>
    /// </summary>
    [TestClass]
    public class ValidationAnnotationsExtensionTests
    {
        #region Types
        public class DirectlyAttributedType
        {
            [TrivialYesNo]
            public string X { get; set; }
            public string Y { get; set; }
            [TrivialYesNo]
            public string Z { get; set; }
        }
        [MetadataType(typeof(ExternalMetdataType))]
        public class ExternallyAttributedType
        {
            public string X { get; set; }
            public string Y { get; set; }
            public string Z { get; set; }

        }
        public class ExternalMetdataType
        {
            [TrivialYesNo]
            public string X { get; set; }
            public string Y { get; set; }
            [TrivialYesNo]
            public string Z { get; set; }
        }
        #endregion

        #region Tests
        [TestMethod]
        public void GetValidationAttributesShouldReturnByType()
        {
            var set = typeof(DirectlyAttributedType).GetValidationAttributes();

            Assert.IsNotNull(set);
            Assert.AreEqual(typeof(DirectlyAttributedType), set.Type);
            AssertHelper.AssertCollectionCount((ICollection)set.PropertyAttributes, 2, "PropertyAttributes");
        }
        [TestMethod]
        public void GetValidationAttributesShouldReturnByProperty()
        {
            var list = typeof(DirectlyAttributedType).GetValidationAttributes("X");

            Assert.IsNotNull(list);
            AssertHelper.AssertListCount<ValidationAttribute>(list, 1, "PropertyAttributes");
            Assert.AreEqual(typeof(TrivialYesNoAttribute), list[0].GetType());

            list = typeof(DirectlyAttributedType).GetValidationAttributes("Y");

            Assert.IsNotNull(list);
            AssertHelper.AssertListCount<ValidationAttribute>(list, 0, "PropertyAttributes");
        }

        [TestMethod]
        public void GetValidationAttributesShouldReturnByTypeWithExternalMetadata()
        {
            var set = typeof(ExternallyAttributedType).GetValidationAttributes(
                new AssociatedMetadataTypeTypeDescriptionProvider(typeof(ExternallyAttributedType)));

            Assert.IsNotNull(set);
            Assert.AreEqual(typeof(ExternallyAttributedType), set.Type);
            AssertHelper.AssertCollectionCount((ICollection)set.PropertyAttributes, 2, "PropertyAttributes");
        }
        [TestMethod]
        public void GetValidationAttributesShouldReturnByPropertyWithExternalMetadata()
        {
            var list = typeof(ExternallyAttributedType).GetValidationAttributes("X",
                new AssociatedMetadataTypeTypeDescriptionProvider(typeof(ExternallyAttributedType)));

            Assert.IsNotNull(list);
            AssertHelper.AssertListCount<ValidationAttribute>(list, 1, "PropertyAttributes");
            Assert.AreEqual(typeof(TrivialYesNoAttribute), list[0].GetType());

            list = typeof(DirectlyAttributedType).GetValidationAttributes("Y");

            Assert.IsNotNull(list);
            AssertHelper.AssertListCount<ValidationAttribute>(list, 0, "PropertyAttributes");
        }
        #endregion
    }
}
